import 'package:dio/dio.dart';
import '../../models/todo_model.dart' as model;
import '../../models/api_response.dart';

/// 待办API服务
class TodoApiService {
  final Dio _dio;

  TodoApiService(this._dio);

  /// 创建待办任务
  Future<ApiResponse<model.TodoModel>> createTodo(
      model.TodoCreateRequest request) async {
    try {
      final response = await _dio.post('/todos', data: request.toJson());
      return ApiResponse.fromJson(
        response.data,
        (json) => model.TodoModel.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取待办任务详情
  Future<ApiResponse<model.TodoModel>> getTodo(int todoId) async {
    try {
      final response = await _dio.get('/todos/$todoId');
      return ApiResponse.fromJson(
        response.data,
        (json) => model.TodoModel.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 更新待办任务
  Future<ApiResponse<model.TodoModel>> updateTodo(
      int todoId, model.TodoUpdateRequest request) async {
    try {
      final response = await _dio.put('/todos/$todoId', data: request.toJson());
      return ApiResponse.fromJson(
        response.data,
        (json) => model.TodoModel.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 删除待办任务
  Future<ApiResponse<void>> deleteTodo(int todoId) async {
    try {
      final response = await _dio.delete('/todos/$todoId');
      return ApiResponse.fromJson(response.data, null);
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取待办任务列表
  Future<ApiResponse<List<model.TodoModel>>> getTodos({
    int? projectId,
    model.TodoStatus? status,
    int? assigneeId,
    DateTime? dueDateFrom,
    DateTime? dueDateTo,
    int page = 0,
    int size = 20,
  }) async {
    try {
      final queryParameters = {
        if (projectId != null) 'projectId': projectId,
        if (status != null) 'status': status.code,
        if (assigneeId != null) 'assigneeId': assigneeId,
        if (dueDateFrom != null) 'dueDateFrom': dueDateFrom.toIso8601String(),
        if (dueDateTo != null) 'dueDateTo': dueDateTo.toIso8601String(),
        'page': page,
        'size': size,
      };

      final response =
          await _dio.get('/todos', queryParameters: queryParameters);
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) =>
                model.TodoModel.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取项目下的待办任务
  Future<ApiResponse<List<model.TodoModel>>> getProjectTodos(
      int projectId) async {
    try {
      final response = await _dio.get('/todos/project/$projectId');
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) =>
                model.TodoModel.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取我的待办任务
  Future<ApiResponse<List<model.TodoModel>>> getMyTodos() async {
    try {
      final response = await _dio.get('/todos/my');
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) =>
                model.TodoModel.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取即将到期的待办任务
  Future<ApiResponse<List<model.TodoModel>>> getTodosNearDeadline() async {
    try {
      final response = await _dio.get('/todos/near-deadline');
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) =>
                model.TodoModel.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取已过期的待办任务
  Future<ApiResponse<List<model.TodoModel>>> getOverdueTodos() async {
    try {
      final response = await _dio.get('/todos/overdue');
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) =>
                model.TodoModel.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 处理错误
  Exception _handleError(dynamic error) {
    if (error is DioException) {
      if (error.response != null) {
        final statusCode = error.response!.statusCode ?? 0;
        // 从响应体中提取错误消息
        String message = '请求失败';
        if (error.response!.data is Map<String, dynamic>) {
          final data = error.response!.data as Map<String, dynamic>;
          message = data['message'] ?? data['error'] ?? message;
        } else if (error.response!.data is String) {
          message = error.response!.data.toString();
        }

        // 根据状态码返回不同的异常类型
        if (statusCode == 401) {
          return const BusinessException(
            message: '认证失败，请重新登录',
            code: 401,
          );
        } else if (statusCode == 403) {
          return const BusinessException(
            message: '权限不足，无法执行此操作',
            code: 403,
          );
        } else if (statusCode >= 500) {
          return BusinessException(
            message: '服务器内部错误，请稍后重试',
            code: statusCode,
          );
        }

        return NetworkException(
          message: message,
          statusCode: statusCode,
          originalError: error,
        );
      } else {
        return const NetworkException(message: '网络连接失败');
      }
    }
    return NetworkException(
      message: error.toString(),
      originalError: error,
    );
  }
}
